using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using System;
using STTech.BytesIO.Core.Entity;
using STTech.BytesIO.Tcp;
using STTech.BytesIO.Tcp.Entity;
using XLua;

public class SocketManager : Singleton<SocketManager>
{
    public string ip;
    public string prot;
    public TcpClient client;


    public LuaFunction connectSuccess = null;
    public LuaFunction dataReceive = null;
    public LuaFunction disconnectServer = null;

    public Queue<string> waitingProtalListSend = new Queue<string>();
    public Queue<string> waitingProtalListReceive = new Queue<string>();


    public string cacheReceive = "";
    public string netStr = "";
    private void Start()
    {
        InitClient();
    }

    private void Update()
    {
        //发送
        if(waitingProtalListSend.Count > 0)
        {
            netStr = waitingProtalListSend.Dequeue();
            if (netStr != null && netStr != "")
            {
                this.Send(netStr);
            }

            netStr = "";
        }


        if(waitingProtalListReceive.Count > 0)
        {
            //接收
            netStr = waitingProtalListReceive.Dequeue();
            if (netStr != null && netStr != "")
            {
                if (this.dataReceive != null)
                {
                    cacheReceive = netStr;
                    dataReceive.Call();
                }
            }
            netStr = "";
        }
    }

    public void AddDataSend(string netStr)
    {
        waitingProtalListSend.Enqueue(netStr);
    }

    public void AddDataReceive(string netStr)
    {
        waitingProtalListReceive.Enqueue(netStr);
    }

    void InitClient()
    {
        if(client== null)
        {
            client = new TcpClient();
            client.OnDataReceived += ClientOnDataReceived;
            client.OnConnectedSuccessfully += ClientOnConnectedSuccessfully;
            client.OnDisconnected += ClientOnDisconnected;
        }
    }


    public void BindCallBack(LuaFunction connectSuccess, LuaFunction dataReceive, LuaFunction disconnectServer)
    {
        this.connectSuccess = connectSuccess;
        this.dataReceive = dataReceive;
        this.disconnectServer = disconnectServer;
    }

    private void ClientOnDisconnected(object sender, DisconnectedEventArgs e)
    {
        if(this.disconnectServer != null)
        {
            disconnectServer.Call();
        }
    }

    private void ClientOnConnectedSuccessfully(object sender, ConnectedSuccessfullyEventArgs e)
    {
        if (this.connectSuccess != null)
        {
            connectSuccess.Call();
        }
    }

    private void ClientOnDataReceived(object sender, DataReceivedEventArgs e)
    {
        //if (this.dataReceive != null)
        //{
        //    Debug.Log(LuaManger.Instance.luaenv.Memroy + "   " + GetMemory());
        //    dataReceive.Call("");
        //}
        this.AddDataReceive(e.Data.EncodeToString());
    }


    public void Connect(string ip, string port)
    {
        InitClient();
        if (!client.IsConnected)
        {
            client.Host = ip;
            client.Port = Int32.Parse(port);
            client.Connect();
        }
    }

    public void Send(string json)
    {
        //var bytes = ProtoFormator.Format(id, table);
        Debug.Log(json);
        client.SendAsync(json.GetBytes());
        //Debug.Log(json);
        //var bytes = json.GetBytes();
        //for(int i = 0; i < bytes.Length; i++)
        //{
        //    Debug.Log(bytes[i]);
        //    Debug.Log($"----{bytes[i]:X2}");
        //}
    }

    internal void Dispose()
    {
        if (client != null && client.IsConnected)
        {
            client.Disconnect();
        }
    }




    public static string GetMemory()
    {
        System.Diagnostics.Process proc = System.Diagnostics.Process.GetCurrentProcess();
        long b = proc.PrivateMemorySize64;
        for (int i = 0; i < 2; i++)
        {
            b /= 1024;
        }
        return b + "MB";
    }


   

}
